package name.bingo.bing.pay.service.trade.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import name.bingo.bing.pay.service.activity.api.IntegralService;
import name.bingo.bing.pay.service.message.api.MessageService;
import name.bingo.bing.pay.service.message.entity.TractionMessage;
import name.bingo.bing.pay.service.trade.api.TradeWriteService;
import name.bingo.bing.pay.service.trade.dao.TradeDao;
import name.bingo.bing.pay.utils.IdGen;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * create by yanbing on 2018/11/9 9:14
 */
@Service
public class TradeWriteServiceImpl implements TradeWriteService {

    @Value("${account-message}")
    private String AccountMessage;
    @Autowired
    private TradeDao tradeDao;
    @Reference
    private MessageService messageService;
    @Reference
    private IntegralService integralService;
    //订单创建
    @Override
    public String orderInit(Map<String,Object> order){
        String result="";
        order.put("id",IdGen.idGen());//id
        order.put("status","c010101");//status
        System.out.println(order.get("userId")+":"+order.get("orderAmount"));
        if(tradeDao.orderInit(order)>0){
            result=(String)order.get("id");
        }
        return result;
    }

    //订单支付成功
    @Override
    public String orderPaySuccess(Map<String,Object> orders){
        //更新支付订单状态+更新支付记录状态  TCC主业务
        tradeDao.orderPaySuccess(orders);
        tradeDao.orderLogPaySuccess(orders);//支付记录处理掉
        Map<String,Object> order=tradeDao.findOrderDetail((String)orders.get("out_trade_no"));
        orders.put("userId",order.get("user_id"));
        orders.put("integral",10);
        //积分账户加款和记录（远程TCC服务）
        String addIntegralResult=integralService.addIntegral(orders);
        //资金账户加款和记录（远程TCC服务）


        //下面是另外一个可靠消息一致性的案例，可根据订单中的是否记账验证下面的事务是否成功
        TractionMessage tractionMessage = preMessageAccount(orders);
        String saveMessageResult=messageService.justSave(tractionMessage);//预发消息
        if(saveMessageResult.equals("ok")){
            //修改订单已记账
            int accountResult=tradeDao.account(orders);
            if(accountResult>0){
                messageService.confirmSend(tractionMessage);//投递消息，成功与否在校验线程中验证
            }
        }
        return "ok";
    }

    //发送会计消息前
    public TractionMessage preMessageAccount(Map<String,Object> orders){
        Map<String, Object> notifyMap = new HashMap<String, Object>();
        String timeEnd = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
        notifyMap.put("transaction_id", IdGen.idGen());//新的消息，新的id
        notifyMap.put("out_trade_no", orders.get("out_trade_no"));
        notifyMap.put("total_amount",orders.get("total_amount"));
        notifyMap.put("time_end", timeEnd);
        String paramJson=JSONObject.fromObject(notifyMap).toString();
        TractionMessage tractionMessage=new TractionMessage((String)notifyMap.get("transaction_id"),paramJson,AccountMessage);
        return tractionMessage;
    }
}
